package abel.wlmr.model.unit;

import java.util.ArrayList;
import java.util.List;

import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import abel.wlmr.model.type.CurvePointBody;
import abel.wlmr.model.type.FlowPointC29Body;
import abel.wlmr.model.type.FlowUnitField;
import io.netty.buffer.ByteBuf;

/**
 * B.5.11.2.4.68 F401：水表正向累积流量示值曲线
 * 数据单元格式见表 B.168。
 * 表B.168 水表正向累积流量曲线数据单元格式
 * 数据内容 数据格式 单位 字节数
 * 曲线类数据时标 Td_c 见本附录 B.5.11.1.3.3 7
 * 正向流量示值 1 见附录 C.29 单位代号 5
 * …… …… …… ……
 * 正向流量示值 n 见附录 C.29 单位代号 5
 * 
 * @author Abel
 *
 */
public class AfnSecondF401Unit extends WlmrBaseUnit {
    private static final short MIN_LENGTH = 7;

    /**
     * 曲线类数据时标 Td_c 见本附录 B.5.11.1.3.3 7
     * 起始时间 ts：分时日月年 见附录 C.15 5
     */
    private CurvePointBody curveTdc;

    /**
     * 正向流量示值 n 见附录 C.29 单位代号 5
     */
    private List<FlowPointC29Body<FlowUnitField>> flowPointList = new ArrayList<>();

    public AfnSecondF401Unit() {
        super();
    }

    public AfnSecondF401Unit(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (curveTdc == null) {
            throw new IllegalArgumentException("curveTdc can't be null");
        }
        if (flowPointList == null) {
            throw new IllegalArgumentException("flowPointList can't be null");
        }
        if (curveTdc.getnPoint() != flowPointList.size()) {
            throw new IllegalArgumentException("not proper size of flow point list: " + curveTdc.getnPoint());
        }
        for (FlowPointC29Body<FlowUnitField> pt : flowPointList) {
            if (pt == null) {
                throw new IllegalArgumentException("none of flow point list can be null");
            }
        }

        curveTdc.appendBuf(buf);
        for (FlowPointC29Body<FlowUnitField> pt : flowPointList) {
            pt.appendBuf(buf);
        }

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        curveTdc = new CurvePointBody(MIN_LENGTH);
        curveTdc.parseBuf(buf);

        int len = MIN_LENGTH + 5 * curveTdc.getnPoint();
        if (getGuessedLength() < len) {
            throw new WlmrException("not enough bcd for flow points");
        }

        for (int i = 0; i < curveTdc.getnPoint(); i++) {
            FlowPointC29Body<FlowUnitField> p1 = new FlowPointC29Body<>(new FlowUnitField());
            p1.parseBuf(buf);

            flowPointList.add(p1);
        }

        return len;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return MIN_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        return (short) (MIN_LENGTH + 5 * curveTdc.getnPoint());
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("{curveTdc:%s, flowPointList:%s}", curveTdc, flowPointList);
    }

    /**
     * B.5.11.1.3.3 曲线类数据时标Td_c
     * 曲线类数据时标 Td_c 的长度为 7 个字节，由要求终端上传的曲线数据的起始时间 ts、数据冻结密度
     * m 和数据点数 n 组成，表示所请求或响应的曲线数据是从起始时间 ts 起，以冻结密度 m 为间隔的连续 n
     * 个点的曲线数据。数据格式见表 B.118。
     * 表B.118 曲线类数据时标 Td_c 数据格式
     * 数据内容 数据格式 字节数
     * 起始时间 ts：分时日月年 见附录 C.15 5
     * 数据冻结密度 m BIN 1
     * 数据点数 n BIN 1
     * 数据冻结密度 m 定义见附录 E
     * 
     * @return the curveTdc
     */
    public CurvePointBody getCurveTdc() {
        return curveTdc;
    }

    /**
     * B.5.11.1.3.3 曲线类数据时标Td_c
     * 曲线类数据时标 Td_c 的长度为 7 个字节，由要求终端上传的曲线数据的起始时间 ts、数据冻结密度
     * m 和数据点数 n 组成，表示所请求或响应的曲线数据是从起始时间 ts 起，以冻结密度 m 为间隔的连续 n
     * 个点的曲线数据。数据格式见表 B.118。
     * 表B.118 曲线类数据时标 Td_c 数据格式
     * 数据内容 数据格式 字节数
     * 起始时间 ts：分时日月年 见附录 C.15 5
     * 数据冻结密度 m BIN 1
     * 数据点数 n BIN 1
     * 数据冻结密度 m 定义见附录 E
     * 
     * @param curveTdc
     *            the curveTdc to set
     */
    public void setCurveTdc(CurvePointBody curveTdc) {
        if (curveTdc == null) {
            throw new IllegalArgumentException("curveTdc can't be null");
        }

        this.curveTdc = curveTdc;
    }

    /**
     * 正向流量示值 n 见附录 C.29 单位代号 5
     * 
     * @return the flowPointList
     */
    public List<FlowPointC29Body<FlowUnitField>> getFlowPointList() {
        return flowPointList;
    }

    /**
     * 正向流量示值 n 见附录 C.29 单位代号 5
     * 
     * @param flowPointList
     *            the flowPointList to set
     */
    public void setFlowPointList(List<FlowPointC29Body<FlowUnitField>> flowPointList) {
        if (flowPointList == null) {
            throw new IllegalArgumentException("flowPointList can't be null");
        }
        for (FlowPointC29Body<FlowUnitField> pt : flowPointList) {
            if (pt == null) {
                throw new IllegalArgumentException("none of flow point list can be null");
            }
        }

        this.flowPointList = flowPointList;
    }
}
